<?php

namespace KernelModule\ModulesModule;

use Albireo\FileSystem\VirtualFileSystem;
use Nette\Object;
use Nette\Environment;
use Albireo\FileSystem\DataFile;
/**
 * Model to parse query from File system console.
 *
 * @author Honza
 */
class FSConsoleModel extends Object {
    /** @var VirtualFileSystem*/
    private $vfs = null;
    /** @var Drivir given by FileSystemDriveFactory*/
    private $driver = "dir/local"; // just for now
    /* @var string Current path*/
    private $path = null;
    /*
     * Set Virtual File system, if user is authenticated in the system.
     *
     * @param string $query
     * @throws Exception if user is not logged in
     */
    public function __construct() {
        $user = Environment::getUser();
        if($user->isLoggedIn()) {
            $this->vfs = new VirtualFileSystem(Environment::getUser());
        } else {
            throw new \Exception("User is not authenticated");
        }
    }

    /*
     * This is like php __call function. it parse incoming query and parse it
     * to name and arguments. Then find corresponding function for name.
     *
     * @param array $query
     * @throws Exception if number of arguments is bigger than 2
     */
    public function parseQuery($query) {
        $query = str_replace(";", "", $query);
        $query = rtrim($query);
//        $log = new DataFile("log.txt", "/");
//        $log->setData($query);
//        $log->setMimetypeText("text/plain");
//        $this->vfs->save($log);
        $exploded = explode(" ", $query);
        $name = $exploded[0];
        $arguments = array();

        for($i=1; $i<count($exploded); $i++) {
            $arguments[] = $exploded[$i];
        }
        if(count($arguments) > 2)
            throw new \InvalidArgumentException("Too much arguments");
        return $this->{$name}($arguments);

        /*
         * Next it will be like this:
         * isFunction (go through array with names of functions)
         * or its operator (go through array with operators)
         * or its argument - gonna be HC
         */

    }

    private function ls($arguments) {
        if(count($arguments) == 0) {
            $pathTemp = $this->parseName($this->path);
        } else {
            $pathTemp = $this->parseName($arguments[0]);
        }
        $name = $pathTemp[0];
        $path = $pathTemp[1];

        $log = new DataFile("log.txt", "/");
        $log->setData($name . " " . $path);
        $log->setMimetypeText("text/plain");
        $this->vfs->save($log);
        
        $dataFile = new DataFile($name, $path);
        return $this->vfs->load($dataFile);

    }

    /*
     * Create the file (text file).
     *
     * @param $arguments with url on first index
     *
     * @throws Exception when wrong number of argumtns is given
     */
    private function touch($arguments) {
        if(count($arguments) != 1) {
            throw new \InvalidArgumentException("Wrong number of arguments");
        }
        $arg = $this->parseName($arguments[0]);
        $dataFile = new DataFile($arg[0], $arg[1]);
        $dataFile->setMimetypeText("text/plain");
        $this->vfs->save($dataFile);
    }

    /*
     * Create directory (recursively).
     *
     * @param $arguments with url on first index
     *
     * @throws Exception when wrong number of argumtns is given
     */
    private function mkdir($arguments) {
        if(count($arguments) != 1) {
            throw new \InvalidArgumentException("Wrong number of arguments");
        }
        $arg = $this->parseName($arguments[0]);
        $dataFile = new DataFile($arg[0], $arg[1]);
//        $df = new DataFile("log.txt", "/");
//        $df->setData($arg[0] . " " . $arg[1]);
//        $df->setMimetypeText("text/plain");
//        $this->vfs->save($df);
        $dataFile->setMimetypeText($this->driver);
        $this->vfs->save($dataFile);
    }

    /*
     * Copy file or directory (recursively).
     *
     * @param $arguments source on index[0] destination on index [2]
     *
     * @throws Exception when wrong number of argumtns is given
     */
    private function cp($arguments) {
        if(count($arguments) != 2) {
            throw new \InvalidArgumentException("Wrong number of arguments");
        }
        $firstArg = $this->parseName($arguments[0]);
        $secondArg = $this->parseName($arguments[1]);

        $df1 = new DataFile($firstArg[0], $firstArg[1]);
        $df2 = new DataFile($secondArg[0], $secondArg[1]);
        $df1->setMimetypeText($this->driver);
        $df2->setMimetypeText($this->driver);

        $this->vfs->copy($df1, $df2);
    }

    private function rm($arguments) {
        if(count($arguments) != 1 ) {
            throw new \InvalidArgumentException("Wrong number of arguments");
        }
        $arg = $this->parseName($arguments);
        $dataFile = new DataFile($arg[0], $arg[1]);
        $dataFile->setMimetypeText("text/plain");
        $this->vfs->delete($dataFile);
    }

    /*
     * Delete directory with all content.
     *
     * @param $arguments with url on first index
     *
     * @throws Exception when wrong number of argumtns is given
     */
    private function rmdir($arguments) {
        if(count($arguments) != 1) {
            throw new \InvalidArgumentException("Wrong number of arguments");
        }
        $arg = $this->parseName($arguments[0]);
        $dataFile = new DataFile($arg[0], $arg[1]);
        $dataFile->setMimetypeText($this->driver);
        $this->vfs->delete($dataFile);
    }

    /*
     * Mostly important function which parse argument tu name and url.
     * 
     * @param $url to be parsed
     * @return $return array which includes name [0] and url [1]
     */
    private function parseName($url) {
        $exploded = explode("/", $url);
        $size = count($exploded);
        $name = $exploded[$size-1];
        $newUrl = "/";
        for($i=0; $i<$size-1; $i++) {
            $newUrl = $newUrl . $exploded[$i] . "/";
        }
        $return[0] = $name;
        $return[1] = $newUrl;
        return $return;
    }

    private function help() {
        $helpArray = array(
            "touch [path]" => "Create file",
            "mkdir [path]" => "Create directory",
            "cp [source] [destination]" => "Copy file or directory",
            "rm [path]" => "Remove file",
            "rmdir [path]" => "Remove directory",
            "help" => "Write help"
        );
        $dataFile = new DataFile(" ", "/");
        return $helpArray;
    }
    

}
